package com.example.zhang.util;

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

public class StatusFrameParser {
    /**
     * 解析上传状态帧，返回主要字段
     * @param frame 完整44字节帧
     * @return 字段Map
     */
    public static Map<String, Object> parseStatusFrame(byte[] frame) {
        Map<String, Object> result = new HashMap<>();
        if (frame == null || frame.length < 44) { // 按协议实际长度
            result.put("error", "帧长度不足，无法解析");
            return result;
        }
        
        // 打印数据帧内容
        StringBuilder sb = new StringBuilder();
        for (byte b : frame) {
            sb.append(String.format("%02X ", b));
        }
        // System.out.println("收到数据帧: " + sb.toString());
        

        // // CRC校验（区间为设备地址到数据区末尾，不含CRC和帧尾）
        // if (frame.length < 10) {
        //     result.put("error", "帧长度不足无法校验CRC");
        //     return result;
        // }
        // int crcStart = 2; // 帧长
        // int crcEnd = frame.length - 6; // 不含CRC和帧尾 和锁
        // byte[] dataForCrc = Arrays.copyOfRange(frame, crcStart, crcEnd);
        // StringBuilder sb1 = new StringBuilder();
        // for (byte b : dataForCrc) {
        //     sb1.append(String.format("%02X ", b));
        // }
        // System.out.println("计算数据帧: " + sb1.toString());
        // byte[] crc = CRC16Util.getCRC16(dataForCrc);
        // if (frame[crcEnd] != crc[0] || frame[crcEnd+1] != crc[1]) {
        //     result.put("error", "CRC校验失败");
        //     System.out.println("CRC校验失败: 帧CRC=" + String.format("%02X %02X", frame[crcEnd], frame[crcEnd+1]) + ", 计算CRC=" + String.format("%02X %02X", crc[0], crc[1]));
        //     return result;
        // }

        // 2. 解析数据
        // 参数区起始字节
        int paramStart = 6;
        // 状态区起始字节
        int statusStart = 24;
        // 设备ID（参数区第1-5字节，5B）
        byte[] deviceIdBytes = Arrays.copyOfRange(frame, paramStart, paramStart + 5);
        StringBuilder deviceIdSb = new StringBuilder();
        for (byte b : deviceIdBytes) {
            deviceIdSb.append(String.format("%02X", b));
        }
        result.put("deviceId", deviceIdSb.toString());
        // 设备地址（参数区第6字节）
        int deviceAddr = frame[paramStart + 5] & 0xFF;
        result.put("deviceAddr", deviceAddr);
        // 设定温度（参数区第11字节）
        byte setTempByte = frame[paramStart + 11];
        double setTemp = parseTempByte(setTempByte);
        result.put("setTemp", setTemp);
        // 温度控制偏差（参数区第12字节）
        int tempDeviation = frame[paramStart + 12] & 0xFF;
        result.put("tempDeviation", tempDeviation);
        // 采集温度（状态区第9字节）
        byte currentTempByte = frame[statusStart + 9];
        double currentTemp = parseTempByte(currentTempByte);
        result.put("currentTemp", currentTemp);
        // 压缩机状态（状态区第7字节）
        int compressorStatus = frame[statusStart + 7] & 0xFF;
        result.put("compressorStatus", compressorStatus);
        // 锁开关状态（状态区第12-13字节，2B，高字节在前，顺序为7~0, 15~8）
        // String lockBytesHex = String.format("%02X %02X", frame[statusStart + 12], frame[statusStart + 13]);
        // System.out.println("锁开关状态原始字节码: " + lockBytesHex);
        List<Integer> lockStates = new ArrayList<>();
        // 高字节bit7~bit0（8~1号锁）
        for (int i = 0; i <=7; i++) {
            lockStates.add((frame[statusStart + 12] >> i) & 1);
        }
        // 低字节bit1和bit0（9~10号锁）
        for (int i = 0; i <=1; i++) {
            lockStates.add((frame[statusStart + 13] >> i) & 1);
        }
        result.put("lockStates", lockStates);
        // 采集时间间隔T2（参数区第8字节，01）
        int uploadInterval = frame[paramStart + 7] & 0xFF;
        result.put("uploadIntervalT2", uploadInterval);
        // 压缩机启动时延T3（参数区第9字节，1E）
        int compressorDelay = frame[paramStart + 8] & 0xFF;
        result.put("compressorDelayT3", compressorDelay);
        return result;
    }

    /**
     * 按协议解析温度字节
     * 7th位：0-非负数，1-负数
     * 1~6th位：温度整数部分（0-63）
     * 0th位：小数部分 1-0.5，0-0
     */
    public static double parseTempByte(byte b) {
        int val = b & 0xFF;
        boolean negative = (val & 0x80) != 0;
        int intPart = (val >> 1) & 0x3F; // 6位整数
        double frac = (val & 0x01) == 1 ? 0.5 : 0.0;
        double temp = intPart + frac;
        return negative ? -temp : temp;
    }

    /**
     * 按帧头帧尾分割出所有完整帧
     */
    public static List<byte[]> splitFrames(byte[] data) {
        List<byte[]> frames = new ArrayList<>();
        int i = 0;
        while (i < data.length - 1) {
            // 找帧头
            if (data[i] == (byte)0xFF && data[i+1] == (byte)0xFF) {
                int start = i;
                // 找帧尾
                for (int j = i + 2; j < data.length - 1; j++) {
                    if (data[j] == (byte)0xFF && data[j+1] == (byte)0xF7) {
                        int end = j + 2; // 包含帧尾
                        byte[] frame = Arrays.copyOfRange(data, start, end);
                        frames.add(frame);
                        i = end - 1;
                        break;
                    }
                }
            }
            i++;
        }
        return frames;
    }

    /**
     * 解析一组数据流，自动分帧并校验，每帧返回一个解析结果
     */
    public static List<Map<String, Object>> parseFrames(byte[] data) {
        List<Map<String, Object>> results = new ArrayList<>();
        List<byte[]> frames = splitFrames(data);
        for (byte[] frame : frames) {
            Map<String, Object> parsed = parseStatusFrame(frame);
            results.add(parsed);
        }
        return results;
    }
} 